import styled from "@emotion/styled";
import { createRef, useEffect, useState } from "react";
import useComponentDidMount from "../hooks/useComponentDidMount";

//楼层容器整体
const StyleStorey = styled.div`
  display: flex;
  align-items: center;
  height: 98px;
  border-bottom: 1px solid var(--elevatorBorderColor--);
`;

//楼层控制
const StyleStoreyController = styled.div`
  width: 70px;
  height: 98px;
  padding: 8px 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
`;

//楼层数
const StyleStoreyCount = styled.div`
  width: 80px;
  height: 98px;
  text-align: center;
  font: 56px / 98px 微软雅黑, 楷体;
`;

//楼层按钮
const StyleButton = styled.button`
  width: 36px;
  height: 36px;
  border: 1px solid var(--elevatorBorderColor--);
  border-radius: 50%;
  outline: none;
  cursor: pointer;
  background-color: var(--elevatorBtnBgColor--);
  &:last-of-type {
    margin-top: 8px;
  }
  &.checked {
    background-color: var(--elevatorBorderColor--);
    color: var(--elevatorBtnBgColor--);
  }
  &[disabled] {
    cursor: not-allowed;
    background-color: var(--elevatorBtnBgDisabledColor--);
    color: var(--elevatorBtnDisabledColor--);
  }
`;

//定义方法类型只能是onUp或者onDown
export interface MethodProps {
  onUp(v: number, t: number, h?: number): void;
  onDown(v: number, t: number, h?: number): void;
}


export interface StoreyProps extends MethodProps {
  count: number
}

export interface StoreyItem {
  key: string
  disabled: boolean
}

const Storey = (props: Partial<StoreyProps>) => {
  //楼层数是动态生成的，不传默认为6
  const { count = 6 } = props;
  //获取当前楼层DOM
  const storeyRef = createRef<HTMLDivElement>();
  //动态生成楼层列表
  const [storeyList, setStoreyList] = useState<StoreyItem[]>();
  //定义一个checked状态，代表当前按钮是否选中
  //存储key值
  const [checked, setChecked] = useState<string>();
  //方法类型
  const [type, setType] = useState<keyof MethodProps>();
  //记录当前楼层高度
  const [offset, setOffset] = useState(0)
  //缓存当前楼层是哪一楼，因为下次点击的时候，我们就需要根据当前楼层来计算，而不是从头开始
  const [currentFloor, setCurrentFloor] = useState(1);
  useComponentDidMount(() => {
    //生成楼层列表
    const res: StoreyItem[] = [];
    //key和楼层数是对应的
    for (let i = count - 1; i >= 0; i--) {
      res.push({
        key: String(i + 1),
        disabled: false
      });
    }
    setStoreyList(res);
  });

  //监听到storeyRef改变，就可以直接拿到dom元素，并且使用一个状态来存储当前高度值
  useEffect(() => {
    if (storeyRef) {
      setOffset(storeyRef.current?.offsetHeight as number)
    }
  }, [storeyRef])

  //禁用或者启用按钮逻辑
  const changeButtonDisabled = (key: string, status: boolean) => {
    //当前楼层不是顶层或者第一层时将checked属性全部修改
    if (+key !== storeyList?.length && +key !== 1) {
      setStoreyList((storey) => storey?.map(item => ({ ...item, disabled: status })))
    }
  }


  //处理向上向下的点击事件
  const onClickHandler = (key: string, index: number, method: keyof MethodProps) => {
    //标记哪个楼层按钮被点击，并且用来改变按钮样式
    setChecked(key)
    //标记当前楼层按钮是触发了“向上”还是“向下”的动作
    setType(method)
    //count 是总楼层数，index 是当前楼层的索引。count - index 的结果表示当前楼层的目标楼层编号
    //比如count是8，则8对应的索引是0，此时8-0=8，刚好得到
    const moveFloor = count - index
    //计算当前楼层与目标楼层的层数差
    const diffFloor = Math.abs(moveFloor - currentFloor)
    //设置当前层
    setCurrentFloor(moveFloor)
    //调用父组件的楼层控制方法，每层楼的高度乘以目标楼层的位置偏移量
    props[method]?.(diffFloor, offset * (moveFloor - 1))
    //禁用按钮
    changeButtonDisabled(key, true)

    //在电梯移动的过程中确保按钮不会影响电梯的运行
    setTimeout(() => {
      //取消选中当前楼层按钮。通过将 checked 状态设置为 undefined，取消按钮的高亮样式。
      setChecked(void 0);
      //启用按钮
      changeButtonDisabled(key, false)
    }, diffFloor * 1000);
  };

  return (
    <>
      {storeyList?.map((item, index) => (
        <StyleStorey key={item.key} ref={storeyRef}>
          <StyleStoreyController>
            <StyleButton
              // 等于楼层最高层时禁用或者等于初始给定的默认值不禁用
              disabled={Number(item.key) === storeyList.length || item.disabled}
              onClick={() => onClickHandler(item.key, index, 'onUp')}
              //被选中并且触发方法是onUp时添加class属性值为checked，其实就是改变了一下样式
              className={`${item.key === checked && type === 'onUp' ? "checked" : ""}`}
            >
              ↑
            </StyleButton>
            <StyleButton
              disabled={Number(item.key) === 1 || item.disabled}
              onClick={() => onClickHandler(item.key, index, 'onDown')}
              className={`${item.key === checked && type === 'onDown' ? "checked" : ""}`}
            >
              ↓
            </StyleButton>
          </StyleStoreyController>
          <StyleStoreyCount>{item.key}</StyleStoreyCount>
        </StyleStorey>
      ))}
    </>
  );
};

export default Storey;